package com.startx.http.system.tool;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;

import com.startx.http.system.constant.Constants;
import com.startx.http.system.constant.Constants.TextTemplate;
import com.startx.http.system.exception.MiniException;
import com.startx.http.system.tool.ResponseBuilder.Code;

/**
 * 参数检查器
 * 
 * @author minghu.zhang
 */
public class BodyContext {

	/**
	 * 参数
	 */
	private Map<String, Object> container = new HashMap<>();
	/**
	 * 异常文本模板
	 */
	private ResourceManager ERORR = TextTemplate.ERORR;
	/**
	 * 手机号正则
	 */
	private Pattern pattern = Pattern.compile("^[1][3-9][0-9]{9}$");

	/**
	 * 构造参数检查器
	 * 
	 * @param param
	 * @return
	 */
	public static BodyContext build(Map<String, ?> param) {
		return new BodyContext(param);
	}

	/**
	 * 有参构造函数
	 * 
	 * @param param
	 */
	private BodyContext(Map<String, ?> param) {
		container.putAll(Objects.isNull(param)?Constants.EMPTY_DICTIONARY:param);
	}

	/**
	 * 无参构造函数
	 */
	public BodyContext() {
	}

	/**
	 * 参数是否存在
	 * @param key
	 * @return
	 */
	public boolean containsKey(String key) {
		return container.containsKey(key);
	}
	
	/**
	 * 获取object
	 * 
	 * @param key
	 * @return
	 */
	public Object getObject(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		return value;
	}
	
	/**
	 * 获取string
	 * 
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (isEmpty(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		return (String) value;
	}

	/**
	 * 获取身份证号
	 * @param key
	 * @return
	 */
	public String getIdentityNo(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (isEmpty(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (!IdentityNo.isIdentityNo(key)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("IdentityCardValidBAD_REQUEST"));
			throw new MiniException(BAD_REQUEST);
		}

		return (String) value;
	}

	/**
	 * 获取long
	 * 
	 * @param key
	 * @return
	 */
	public long getLong(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (!isLong(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamTypeErrorNeetLong",key));
			throw new MiniException(BAD_REQUEST);
		}

		return Long.valueOf(value.toString());
	}

	/**
	 * 获取int
	 * 
	 * @param key
	 * @return
	 */
	public int getInt(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (!isInt(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamTypeErrorNeetInt",key));
			throw new MiniException(BAD_REQUEST);
		}

		return Integer.valueOf(value.toString());
	}

	/**
	 * 获取电话号码
	 * @param key
	 * @return
	 */
	public String getTelephone(String key) {
		Object value = container.get(key);

		if (isNull(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamCanNotEmpty",key));
			throw new MiniException(BAD_REQUEST);
		}

		if (!isTelephone(value)) {
			Code BAD_REQUEST = Code.BAD_REQUEST;
			BAD_REQUEST.setMsg(ERORR.getString("ParamTypeErrorNeetTelephone",key));
			throw new MiniException(BAD_REQUEST);
		}

		return (String) value;
	}

	/**
	 * 参数检查
	 * 
	 * @param args
	 * @return
	 */
	private boolean isNull(Object arg) {
		return Objects.isNull(arg);
	}

	/**
	 * 检查参数是否为整数
	 * 
	 * @param args
	 * @return
	 */
	private boolean isInt(Object arg) {
		Class<? extends Object> clz = arg.getClass();
		return clz.equals(int.class) || 
			   clz.equals(Integer.class);
	}

	/**
	 * 检查参数是否为长整型
	 * 
	 * @param args
	 * @return
	 */
	private boolean isLong(Object arg) {
		Class<? extends Object> clz = arg.getClass();
		return clz.equals(long.class) || 
			   clz.equals(Long.class) || 
			   clz.equals(int.class) || 
			   clz.equals(Integer.class);
	}

	/**
	 * 检查参数是否为空
	 * 
	 * @param args
	 * @return
	 */
	private boolean isEmpty(Object arg) {
		return "".equals(arg.toString());
	}

	/**
	 * 检查手机号格式
	 * 
	 * @param args
	 * @return
	 */
	private boolean isTelephone(Object arg) {
		return pattern.matcher(arg.toString()).matches();
	}

}
